Public Class ColumnarTranspositionCipherEngine

    Function Encrypt(ByVal PlainText As String, ByVal Key As String) As String
        'Compute columns amount
        Dim ColumnNum As Byte = Key.Length

        'Compute rows amount
        Dim RowNum As Byte = PlainText.Length \ Key.Length
        If (PlainText.Length Mod Key.Length) > 0 Then RowNum += 1

        Dim CharMatrix(RowNum - 1, ColumnNum - 1) As Char
        Dim CharArray(CharMatrix.Length - 1) As Char

        'Fill plaintext charrecters order left to right in rows matrix (2 Dimension Array)
        Dim Count As Byte = 0
        For CountRow As Byte = 0 To RowNum - 1
            For CountCol As Byte = 0 To ColumnNum - 1
                If Count <= PlainText.Length - 1 Then
                    CharMatrix(CountRow, CountCol) = PlainText(Count)
                    Count += 1
                Else
                    CharMatrix(CountRow, CountCol) = Nothing
                End If
            Next CountCol
        Next CountRow

        'Read each column charrecters order top-down  to string
        Count = 0
        For CountCol As Byte = 1 To Key.Length
            'find column index in order and put in ColumnOrder
            Dim ColumnOrder As Byte
            For ColumnOrder = 0 To Key.Length - 1
                Dim Num As Byte = CByte(Key(ColumnOrder).ToString)
                If CountCol = Num Then Exit For
            Next ColumnOrder

            For CountRow As Byte = 0 To RowNum - 1
                If Not CharMatrix(CountRow, ColumnOrder) = Nothing Then
                    CharArray(Count) = CharMatrix(CountRow, ColumnOrder)
                    Count += 1
                End If
            Next CountRow
        Next CountCol

        'Convert array of charecters to string
        Return CharArray
    End Function

    Function Decrypt(ByVal CipherText As String, ByVal Key As String) As String
        'Compute columns amount
        Dim ColumnNum As Byte = Key.Length

        'Compute empty cell (of matrix)
        Dim EmptyNum As Byte
        Dim CharTotal As Byte = CipherText.Length
        Dim Fraction As Byte = CharTotal Mod ColumnNum
        EmptyNum = IIf(Fraction = 0, 0, ColumnNum - Fraction)

        'Compute rows amount
        Dim RowNum As Byte = CipherText.Length \ Key.Length
        If (CipherText.Length Mod Key.Length) > 0 Then RowNum += 1

        Dim CharMatrix(RowNum - 1, ColumnNum - 1) As Char
        Dim CharArray(CharMatrix.Length - 1) As Char

        'Fill CipherText charecter order top-down in each column on matrix (2 dimension array)
        Dim Count As Byte = 0
        For CountCol As Byte = 1 To Key.Length
            'Find column index in order and store in ColumnOrder
            Dim ColumnOrder As Byte
            For ColumnOrder = 0 To Key.Length - 1
                Dim Num As Byte = CByte(Key(ColumnOrder).ToString)
                If CountCol = Num Then Exit For
            Next ColumnOrder

            'for complete column (not exist empty cell)
            If ColumnOrder <= (Key.Length - 1 - EmptyNum) Then
                For CountRow As Byte = 0 To RowNum - 1
                    CharMatrix(CountRow, ColumnOrder) = CipherText(Count)
                    Count += 1
                Next CountRow
            Else 'for empty cell (Nothing value) in column
                For CountRow As Byte = 0 To RowNum - 2
                    CharMatrix(CountRow, ColumnOrder) = CipherText(Count)
                    Count += 1
                Next CountRow
            End If
        Next CountCol

        'Read charecters in matrix rows from left-right to string
        Count = 0
        For CountRow As Byte = 0 To RowNum - 1
            For CountCol As Byte = 0 To ColumnNum - 1
                If Count <= CipherText.Length - 1 Then
                    CharArray(Count) = CharMatrix(CountRow, CountCol)
                    Count += 1
                End If
            Next CountCol
        Next CountRow

        'Convert array of charecters to string
        Return CharArray
    End Function

End Class
